package com.lebang.configuration.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.lebang.common.ValidCode;
import com.lebang.component.RedisClient;
import com.lebang.domain.ValidConfig;
import com.lebang.domain.ValidMemberRecord;
import com.lebang.entity.RequestHeaders;
import com.lebang.example.ValidMemberRecordExample;
import com.lebang.mapper.ValidConfigMapper;
import com.lebang.mapper.ValidMemberRecordMapper;
import com.lebang.model.Whether;
import com.lebang.service.MemberBlackService;
import com.lebang.service.sys.ValidMemberRecordService;
import com.lebangweb.response.Callback;
import com.lebangweb.response.JsonData;
import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

import static com.lebang.service.buss.MemberTradeService.CATEGORY_KEY;

/**
 * 自定义拦截器
 * 验证抓包黑名单
 *
 * @author hwq
 */
@Component
public class RouseInterceptor implements HandlerInterceptor {
    @Autowired
    private MemberBlackService memberService;
    private static final Logger log = LoggerFactory.getLogger(RouseInterceptor.class);
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private ValidConfigMapper validConfigMapper;
    @Autowired
    private ValidMemberRecordMapper validMemberRecordMapper;
    @Autowired
    private ValidMemberRecordService validMemberRecordService;

    /**
     * 该方法将在请求处理之前进行调用，只有该方法返回true，才会继续执行后续的Interceptor和Controller，
     * 当返回值为true 时就会继续调用下一个Interceptor的preHandle 方法，
     * 如果已经是最后一个Interceptor的时候就会是调用当前请求的Controller方法
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
        if (!(object instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) object;
        Method method = handlerMethod.getMethod();

        if (method.isAnnotationPresent(ValidCode.class)) {
            RequestHeaders requestHeaders = new RequestHeaders(request);
            ValidCode userLoginToken = method.getAnnotation(ValidCode.class);
            if (userLoginToken.required()) {
                if(redisClient.exists("member:code:"+requestHeaders.getUserid())){
                    response.setHeader("back","back");
                    return true;
                }
                ValidMemberRecordExample example = new ValidMemberRecordExample();
                example.createCriteria().andCreateDateEqualTo(LocalDate.now())
                        .andMemberIdEqualTo(requestHeaders.getUserid());
                example.setOrderByClause("count asc");
                List<ValidMemberRecord> validMemberRecord = validMemberRecordMapper.selectByExample(example);
                //现在是第几次弹窗
                int now = validMemberRecordService.getNowCount(validMemberRecord);
                int count = redisClient.Optionalhget(CATEGORY_KEY + "ALL:" +
                        LocalDate.now().format(DateTimeFormatter.ISO_DATE), requestHeaders.getUserid()).map(Integer::parseInt).orElse(2);
                count--;
                //获取第几次弹窗的配置
                ValidConfig config = validConfigMapper.selectByCount(now);
                if (config != null) {
                    if (config.getStar() < count) {
                        config.setStar(count);
                    }
                    if(config.getStar()>config.getEnd()){
                        return true;
                    }
                    int random = RandomUtils.nextInt(config.getStar(), config.getEnd()+1);
                    if (random == count && validMemberRecordService.checkNow(validMemberRecord, config)) {
                        ValidMemberRecord record = new ValidMemberRecord();
                        record.setHasDeleted(0);
                        record.setCreateTime(LocalDateTime.now());
                        record.setModifyTime(LocalDateTime.now());
                        record.setCount(config.getCount());
                        record.setMemberId(requestHeaders.getUserid());
                        record.setCreateDate(LocalDate.now());
                        record.setCheckCount(random);
                        record.setImei(requestHeaders.getImei());
                        record.setIpAddress(requestHeaders.getIpAddr());
                        record.setAppStore(requestHeaders.getAppStore());
                        record.setVersion(requestHeaders.getVersion());
                        record.setMacAddr(requestHeaders.getMacAddr());
                        record.setOsv(requestHeaders.getOsv());
                        record.setConfigId(config.getId());
                        record.setPoint(config.getPoint());
                        record.setStatus(Whether.NO.getDbIndex());
                        String code= String.valueOf(RandomUtils.nextInt(1001,10000));
                        code=code.replace("7","2").replace("1","4");
                        record.setValidCode(code);
                        validMemberRecordMapper.insertSelective(record);
                        redisClient.setex("member:code:"+requestHeaders.getUserid(),code,config.getReleaseTime()*60);
                        response.setHeader("back","back");
                    }
                }
            }
        }

        return true;
    }

    private void responseMsg(HttpServletResponse response, String status, String msg) throws IOException {
        JsonData jsonData = Callback.fail(status, msg, "");
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json; CHARSET=utf-8");
        String json = JSONObject.toJSONString(jsonData);
        PrintWriter out = response.getWriter();
        out.print(json);
        out.flush();
        out.close();
    }


    /**
     * 该方法将在请求处理之后，DispatcherServlet进行视图返回渲染之前进行调用，可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行，该方法将在整个请求结束之后，也就是在DispatcherServlet 渲染了对应的视图之后执行。用于进行资源清理
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) throws Exception {

    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println(RandomUtils.nextInt(0,5));
        }
    }
}
